package br.com.arg.aplica.data;

import br.com.arg.aplica.model.Sistema;
import br.com.arg.aplica.util.AlinhamentoCampo;
import br.com.arg.aplica.util.TipoCampo;
import br.com.arg.aplica.util.TipoCampoTela;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;

import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

//The @Stateful annotation eliminates the need for manual transaction demarcation
@Stateful
//The @Model stereotype is a convenience mechanism to make this a
//request-scoped bean that has an
//EL name
//Read more about the @Model stereotype in this FAQ:
//http://sfwk.org/Documentation/WhatIsThePurposeOfTheModelAnnotation
@Named 
@SessionScoped 
public class SistemaListProducer {
	@Inject
	private EntityManager em;

	private List<Sistema> sistemas;

	// Generated by Map
	private Map<String, Long> mapCasosDeUso;
	private Map<String, Long> mapSistemas;
	@Produces 	@Named	
	public Map<String, Long> getMapSistemas() {
		mapSistemas = new LinkedHashMap<String, Long>();
		for (Sistema apl : sistemas) {
			mapSistemas.put(apl.getNome(), apl.getId()); // label, value
		}
		return mapSistemas;
	}

	// Generated by Map
	@Produces @Named	
	public Map<String, TipoCampo> getMapTipoCampo() {
		return TipoCampo.lookup;
	}

	// Generated by Map
	@Produces @Named	
	public Map<String, Integer> getMapAlinhamento() {
		return AlinhamentoCampo.lookup;
	}

	// Generated by Map
	@Produces	@Named	
	public Map<String, Integer> getMapTipoCampoTela() {
		return TipoCampoTela.lookup;
	}
	
	// @Named provides access the return value via the EL variable name
	// "members" in the UI (e.g.,
	// Facelets or JSP view)
	@Produces	@Named
	public List<Sistema> getSistemas() {
		return sistemas;
	}

	public void onAplicaListChanged(
			@Observes(notifyObserver = Reception.IF_EXISTS) final Sistema sistema) {
		retrieveAllSistemasOrderedByName();
	}

	@PostConstruct
	public void retrieveAllSistemasOrderedByName() {
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<Sistema> criteria = cb.createQuery(Sistema.class);
		Root<Sistema> aplica = criteria.from(Sistema.class);
		criteria.select(aplica).orderBy(cb.asc(aplica.get("nome")));
		sistemas = em.createQuery(criteria).getResultList();
	}
}
